package com.example.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import com.example.common.StatusText;
import com.example.dao.UserDao;
import com.example.entity.bean.UserBean;
import com.example.entity.entity.UserEntity;
import com.example.security.JwtTokenUtil;
import com.example.service.UserService;

@Service
public class UserService {

	private AuthenticationManager authenticationManager;
	private UserDetailsService userDetailsService;
	private JwtTokenUtil jwtTokenUtil;
	private UserDao userDao;

	@Value("${jwt.tokenHead}")
	private String tokenHead;

	@Autowired
	public UserService(AuthenticationManager authenticationManager, UserDetailsService userDetailsService,
			JwtTokenUtil jwtTokenUtil, UserDao userRepository) {
		this.authenticationManager = authenticationManager;
		this.userDetailsService = userDetailsService;
		this.jwtTokenUtil = jwtTokenUtil;
		this.userDao = userRepository;
	}

	public HashMap<String, Object> login(String username, String password) {
		try {
			UsernamePasswordAuthenticationToken upToken = new UsernamePasswordAuthenticationToken(username, password);
			Authentication authentication = authenticationManager.authenticate(upToken);
			SecurityContextHolder.getContext().setAuthentication(authentication);
			UserDetails userDetails = userDetailsService.loadUserByUsername(username);
			HashMap<String, Object> map = new HashMap<String, Object>();
			map.put("token", jwtTokenUtil.generateToken(userDetails));
			map.put("user", userDao.getUser(username));
			return map;
		} catch (Exception e) {
			return null;
		}
	}

	public Integer register(UserBean userBean) {
		String username = userBean.getUsername();
		if (userDao.findByUsername(username) != null) {
			return StatusText.USER_REGISTER_EXIST;
		}
		BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
		String rawPassword = userBean.getPassword();
		userBean.setPassword(encoder.encode(rawPassword));
		List<String> roles = new ArrayList<>();
		roles.add("ROLE_ADMIN");
		roles.add("ROLE_USER");
		userBean.setRoles(roles);
		UserEntity userEntity = new UserEntity(userBean);
		if (userDao.insert(userEntity) > 0) {
			return StatusText.USER_REGISTER_SUCCESS;
		} else {
			return StatusText.USER_REGISTER_FAIL;
		}
	}

	public String refreshToken(String oldToken) {
		String token = oldToken.substring(tokenHead.length());
		if (!jwtTokenUtil.isTokenExpired(token)) {
			return jwtTokenUtil.refreshToken(token);
		}
		return "error";
	}

}
